#version 450
precision highp float;

layout(location = 0) in vec4 fragColor;
layout(location = 1) flat in vec2 lineStart;
layout(location = 2) flat in vec2 lineEnd;
layout(location = 3) flat in float lineHalfWidth;
layout(location = 4) flat in uint lineCapType;

layout(location = 0) out vec4 outColor;

void main() {
    vec2 ab = lineEnd - lineStart;
    vec2 ap = gl_FragCoord.xy - lineStart;
    float projec = dot(ap, ab) / dot(ab, ab);
    projec = clamp(projec, 0.0, 1.0);
    vec2 closest = lineStart + projec * ab;
    float dist = distance(gl_FragCoord.xy, closest);
    float alpha = 1.0 - smoothstep(lineHalfWidth - 1.8, lineHalfWidth, dist);
    float len = distance(lineStart, lineEnd);
    if (lineCapType == 1) {
        float tran = lineHalfWidth / len;
        float term = clamp(projec, tran, 1.0 - tran);
        float site = projec - term;
        tran = abs(site) * len;
        if (tran > 0.0) {
            vec2 lineDir = normalize(ab) * lineHalfWidth;
            if (site < 0) {
                dist = distance(gl_FragCoord.xy, lineStart + lineDir);
            }
            else {
                dist = distance(gl_FragCoord.xy, lineEnd - lineDir);
            }
            if (dist > lineHalfWidth)
                discard;
            alpha = min(alpha, 1.0 - smoothstep(lineHalfWidth - 1.8, lineHalfWidth, dist));
        }
    }
    else {
        float tran = 2 / len;
        float term = clamp(projec, tran, 1.0 - tran);
        tran = abs(projec - term) * len;
        if (tran > 0.0) {
            alpha = min(alpha, 1.0 - smoothstep(0.2, 2.0, tran));
        }
    }
    outColor = vec4(fragColor.rgb, fragColor.a * alpha);
}